#include <iostream>
#include "LineItem.h"
#include <QGraphicsItem>

const QString LineItem::CLASSNAME = QString( "LineItem" );
///*
const QString ItemControlPoint::CLASSNAME = QString( "ItemControlPoint" );

ItemControlPoint::ItemControlPoint( QGraphicsItem * parent )
: QGraphicsRectItem( parent ) 
{
  className = ItemControlPoint::CLASSNAME;
  defaultPen = QPen( QColor( 50, 50, 255, 255 ), 2.0 );
  defaultPen.setJoinStyle( Qt::RoundJoin );
  setPen( defaultPen );
  setBrush( QBrush( Qt::NoBrush) );
  owner = parent;
  selected = false;
}

QRectF ItemControlPoint::boundingRect() const {
  //  qreal penWidth = 4;
  //  QRectF qr( rect.x()-penWidth/2, rect.y()-penWidth/2, rect.width()+penWidth/2, rect.height()+penWidth/2);
  return QGraphicsRectItem::rect();
}


void ItemControlPoint::paint( QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget ){
  //  ppainter ->setBrush( Qt::NoBrush );
  //  ppainter->setPen( QPen( QColor( 0, 0,255,255 ), pen().width()+2 ));
  ppainter->setPen( QPen( QColor( 0, 0,255,255 ), 1 ));
  if( isSelected() ){
  //  ppainter->setBrush( QBrush( QColor(255  ,0,255,10)) );
    ppainter->setBrush( QBrush( Qt::red) );
  }else{
    ppainter->setBrush( QBrush( Qt::blue) );
  }
  //    setBrush(defaultBrush = QBrush( QColor(0,0,255,10)) );
  ppainter->drawRect(QGraphicsRectItem::rect());
 }

void ItemControlPoint::mousePressEvent( QGraphicsSceneMouseEvent *pe )
{
  std::cout << "ItemControlPoint::mousePressEvent" << std::endl;
  if( isSelected()) {
  std::cout << "ItemControlPoint::mousePressEvent:isSelected == true" << std::endl;
    if ( selected ){
      selected = false;
    }else{
      selected = true;
    }
  }
  QGraphicsItem::mousePressEvent( pe );
}

void ItemControlPoint::mouseMoveEvent( QGraphicsSceneMouseEvent *pe )
{
  std::cout << "ItemControlPoint::mouseMoveEvent" << std::endl;
  if( isSelected()) {
    std::cout << "ItemControlPoint::mouseMoveEvent::isSelected" << std::endl;
  
    QPointF pf = mapToScene( pe->pos() ); //current position on scene
    QPointF rect_pos = mapToScene( rect().center() );// rect center allways == (0,0) -> do mapToScene
    QPointF null_pointf( 0, 0 );
    LineItem *litem = (LineItem*)owner;
    QLineF newLine; 
    if ( litem ){

      std::cout << "ItemControlPoint::mouseMoveEvent::isSelected litem rect_pos=("
		<< rect_pos.x() << ", "
		<< rect_pos.y() << ") cur pos=("
		<< pf.x() << ", "
		<< pf.y() << ")," << std::endl
		<< "line p1=("
		<< litem->QGraphicsLineItem::line().p1().x() << ", "
		<< litem->QGraphicsLineItem::line().p1().y() << "), p2=("
		<< litem->QGraphicsLineItem::line().p2().x() << ", "
		<< litem->QGraphicsLineItem::line().p2().y() << ")"
		<< std::endl;
      ItemControlPoint * icp;
      QList<QGraphicsItem*>::const_iterator ci;
      ci = litem->list_control_point.begin();
      int i=0;
      QPointF offsetf, mdlp;
      for( ci; ci < litem->list_control_point.end(); ++ci, ++i ){
	icp = (ItemControlPoint*) *ci;

	if( ((QGraphicsRectItem*)*ci)->pos() != rect_pos ) { 
	  continue;
	}else { 
	  //	  offsetf = ((QGraphicsRectItem*)*ci)->pos() - rect_pos;
	  std::cout << "ItemControlPoint::mouseMoveEvent::isSelected rect().center()="
		    << mapToScene( ((ItemControlPoint*)*ci)->pos() ).x() << " "
		    << mapToScene( ((ItemControlPoint*)*ci)->pos() ).y() << "("
		    << ((ItemControlPoint*)*ci)->pos().x() << " "
		    << ((ItemControlPoint*)*ci)->pos().y() << ")" << std::endl;
	  mdlp = rect_pos;
	  break;
	}
      }
      std::cout << "ItemControlPoint::mouseMoveEvent::isSelected i=" << i << std::endl;
      switch( i ){
      case 0: //begin line
	newLine.setPoints(pf, litem->QGraphicsLineItem::line().p2());
	setPos( pf ); //move rect to current point 
	litem->setLine( newLine );
	break;
      case 1: //end line
	newLine.setPoints(litem->QGraphicsLineItem::line().p1(), pf);
	setPos( pf ); //move rect to current point 
	litem->setLine( newLine );
	break;
      case 2: //midle line
	break;
      default:
	std::cout << "ItemControlPoint::mouseMoveEvent::isSelected no set line" << std::endl;
	break;
   
      }

      std::cout << "ItemControlPoint::mouseMoveEvent::isSelected set line to (" 
		<< litem->QGraphicsLineItem::line().p1().x() << " " 
		<< litem->QGraphicsLineItem::line().p1().y() << ", " 
		<< litem->QGraphicsLineItem::line().p2().x() << " "
		<< litem->QGraphicsLineItem::line().p2().y() << ")" << std::endl
		<< "center line:(" << null_pointf.x() << ", " << null_pointf.y() << ")" << std::endl;
    }else{
      std::cout << "ItemControlPoint::mouseMoveEvent::isSelected no cast to LineItem" << std::endl;
    }
    if ( selected ){
      selected = false;
    }else{
      selected = true;
    }
  }
  QGraphicsItem::mouseMoveEvent( pe );
}

void ItemControlPoint::mouseReleaseEvent( QGraphicsSceneMouseEvent *pe ){
  QPointF pf = mapToScene( pe->pos() ); //current position on scene
  QPointF rect_pos = mapToScene( rect().center() );// rect center allways == (0,0) -> do mapToScene
  QPointF null_pointf( 0, 0 );
  LineItem *litem = (LineItem*)owner;
  QLineF newLine; 
  QPointF offsetf, mdlp;

  offsetf = rect_pos - pf;
  std::cout << "ItemControlPoint::mouseReleaseEvent offsetf=(" 
	    << offsetf.x() << ", "
	    << offsetf.y() << ")" << std::endl;
  if( isSelected()) {
      ItemControlPoint * icp;
      QList<QGraphicsItem*>::const_iterator ci;
      ci = litem->list_control_point.begin();
      int i=0;

      for( ci; ci < litem->list_control_point.end(); ++ci, ++i ){
	icp = (ItemControlPoint*) *ci;

	if( ((QGraphicsRectItem*)*ci)->pos() != rect_pos ) { 
	  continue;
	}else { 
	  //	  offsetf = ((QGraphicsRectItem*)*ci)->pos() - rect_pos;
	  std::cout << "ItemControlPoint::mouseReleaseEvent::isSelected rect().center()="
		    << mapToScene( ((ItemControlPoint*)*ci)->pos() ).x() << " "
		    << mapToScene( ((ItemControlPoint*)*ci)->pos() ).y() << "("
		    << ((ItemControlPoint*)*ci)->pos().x() << " "
		    << ((ItemControlPoint*)*ci)->pos().y() << ")" << std::endl;
	  mdlp = rect_pos;
	  break;
	}
      }
      switch( i ){
      case 0: //begin line
	newLine.setPoints(pf, litem->QGraphicsLineItem::line().p2());
	setPos( pf ); //move rect to current point 
	litem->setLine( newLine );
	break;
      case 1: //end line
	newLine.setPoints(litem->QGraphicsLineItem::line().p1(), pf);
 	setPos( pf ); //move rect to current point 
	litem->setLine( newLine );
	break;
      case 2: //midle line
	/*
	newLine = litem->QGraphicsLineItem::line().translated( pf );
	litem->setLine( newLine );
	setPos( (newLine.p1() - newLine.p2())/2 );
	//	setPos( pf );
	*/
	break;
      }
  }
    if ( selected ){
      selected = false;
    }else{
      selected = true;
    }

  QGraphicsItem::mouseMoveEvent( pe );
}

//*/

LineItem::LineItem( QGraphicsItem * parent ) 
: QGraphicsLineItem( parent ) 
{
  className = LineItem::CLASSNAME;
  defaultPen = QPen( QColor( 50, 50, 255, 255 ), 2.0 );
  defaultPen.setJoinStyle( Qt::RoundJoin );
  setPen( defaultPen );
  selected = false;
  cm.y0 = cm.y1 = 0;
  //  setBrush( defaultBrush = Qt::NoBrush );

 }
 
LineItem::LineItem( const QLineF & _line, QGraphicsItem * parent, Tinkercell::GraphicsScene * scene)
: QGraphicsLineItem( parent ) 
{
  className = LineItem::CLASSNAME;
  defaultPen = QPen( QColor( 50, 50, 255, 255 ), 2.0 );
  defaultPen.setJoinStyle( Qt::RoundJoin );
  setPen( defaultPen );
  selected = false;
  cm.y0 = cm.y1 = 0;
  setLine( _line );
  this->scene = scene;
}

QRectF LineItem::boundingRect() const {
  //  QRectF a; //( QGraphicsLineItem::line().p1(), QGraphicsLineItem::line.p2() );
  QPointF p1, p2;
  p1 = QGraphicsLineItem::line().p1();
    p2 = QGraphicsLineItem::line().p2();
  //  a.setRect(QGraphicsLineItem::line().p1(), QGraphicsLineItem::line.p2() );
  QRectF a( p1, p2 );
  return a;
}


void LineItem::paint( QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget ){
  ppainter ->setBrush( Qt::NoBrush );
  ppainter->setPen( QPen( QColor( 0, 0,255,255 ), pen().width()+2 ));
  ppainter->drawLine(QGraphicsLineItem::line());
}


void LineItem::mousePressEvent( QGraphicsSceneMouseEvent *pe )
{
  std::cout << "LineItem::mousePressEvent" << std::endl;
  if( isSelected()) {
     if ( selected ){
      QList<QGraphicsItem*>selectedItems;
      selectedItems = scene->selected();
	  std::cout << "LineItem::mousePressEvent: selected" << std::endl;

	QGraphicsItem * qgitem;

      if( selectedItems.size() > 1 ){
	// selected rect and line
	std::cout <<  "LineItem::mousePressEvent::selected line and rect" << std::endl;
      
      }else {

	//selected only line
	//      QList<QGraphicsRectItem*>::iterator i = list_control_point.begin();
      	QList<QGraphicsItem*>::iterator i = list_control_point.begin();
	//	QList<ItemControlPoint*>::iterator i = list_control_point.begin();
	for( i; i != list_control_point.end(); ++i){
	  scene->removeItem( *i );
	  delete *i;
	}

	list_control_point.clear();
	selected = false;
      }
    }else{
      QRectF rf(-5, -5, 10, 10 );

      selected = true;
      ItemControlPoint * icp_mdl = new ItemControlPoint( this );
      ItemControlPoint * icp_beg = new ItemControlPoint( this );
      ItemControlPoint * icp_end = new ItemControlPoint( this );

      icp_mdl->setRect( rf );
      icp_beg->setRect( rf );
      icp_end->setRect( rf );

      icp_mdl->setPos(( QGraphicsLineItem::line().p1() + QGraphicsLineItem::line().p2() )/2);
      icp_beg->setPos( QGraphicsLineItem::line().p1() );
      icp_end->setPos( QGraphicsLineItem::line().p2() );

	icp_mdl->setFlag( QGraphicsItem::ItemIsSelectable, true );
	icp_mdl->setFlag( QGraphicsItem::ItemIsMovable, true );
	icp_beg->setFlag( QGraphicsItem::ItemIsSelectable, true );
	icp_beg->setFlag( QGraphicsItem::ItemIsMovable, true );
	icp_end->setFlag( QGraphicsItem::ItemIsSelectable, true );
	icp_end->setFlag( QGraphicsItem::ItemIsMovable, true );

	icp_mdl->setZValue( 100 );
	icp_beg->setZValue( 100 );
	icp_end->setZValue( 100 );
	icp_mdl->setBrush( QBrush( Qt::red ));

	QGraphicsRectItem * gri = new QGraphicsRectItem( this );
	gri->setRect( rf );
	gri->setPos( pe->pos() );
	gri->setFlag( QGraphicsItem::ItemIsSelectable, true );
	gri->setFlag( QGraphicsItem::ItemIsMovable, true );
	gri->setBrush( QBrush( Qt::yellow ));
	list_control_point << icp_beg << icp_end << icp_mdl << gri; // << gri; add to scene from scene->insert
      scene->insert( "insert ItemControlPoint", list_control_point );
      //      scene->insert( "insert yellow ControlPoint", gri );
      cm.y0 = 1; //start automatic
      run( e2 );
    }
  }
  QGraphicsItem::mousePressEvent( pe );
}

void LineItem::run( Event e ){
  while( cm.y0 ){
    step( e );
  }

}
void LineItem::step( Event e ){
  int old_y = cm.y0;
  switch( cm.y0 ){
  case s0:
    break;
  case s1:
    cm.y0 = s0; //to stop
    break;
  default: 
    break;
  }if( old_y == cm.y0 ){
    //Loop
  }else{
    switch( cm.y0 ){
    case s0:
      std::cout << "LineItem::mousePressEvent::state s0" << std::endl;
      break;
    case s1:
      break;
    default:
      break;
    }
  }
}
